package com.andnnl.template;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.fasterxml.jackson.databind.JsonNode;

import cn.hutool.core.util.StrUtil;
import dk.brics.automaton.Automaton;
import dk.brics.automaton.RegExp;
import dk.brics.automaton.State;
import dk.brics.automaton.Transition;


public class ParamUtil {
    private final static Random random = new Random();
    // 辅助方法：生成随机字符串
    public static String generateRandomString(int length) {
        Random rand = new Random();
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            int charType = rand.nextInt(3);
            switch (charType) {    
                case 0: // 大写字母
                    sb.append((char) (rand.nextInt(26) + 'A'));
                    break;
                case 1: // 小写字母
                    sb.append((char) (rand.nextInt(26) + 'a'));
                    break;
                default: // 数字
                    sb.append(rand.nextInt(10));
            }
        }
        return sb.toString();
    }

    // 生成符合正则表达式的字符串
    public static String generate(String regexPattern) {
        try {
            // 转换正则表达式为自动机
            RegExp regex = new RegExp(regexPattern);
            Automaton automaton = regex.toAutomaton();
            
            // 从初始状态开始生成字符串
            StringBuilder sb = new StringBuilder();
            generatePath(automaton.getInitialState(), sb);
            return sb.toString();
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("无效的正则表达式: " + regexPattern, e);
        }
    }

    private static void generatePath(State currentState, StringBuilder sb) {
        // 检查是否到达接受状态
        if (currentState.isAccept()) {
            // 40% 概率提前结束
            if (random.nextDouble() < 0.4) return;
        }
        
        // 获取有效转移
        List<Transition> transitions = new ArrayList<>();
        for (Transition t : currentState.getTransitions()) {
            transitions.add(t);
        }
        
        // 随机选择转移路径
        if (!transitions.isEmpty()) {
            Transition randomTrans = transitions.get(random.nextInt(transitions.size()));
            char randomChar = getRandomCharInRange(randomTrans.getMin(), randomTrans.getMax());
            sb.append(randomChar);
            generatePath(randomTrans.getDest(), sb);
        }
    }

    // 生成范围内的随机字符
    private static char getRandomCharInRange(char min, char max) {
        return (char) (min + random.nextInt(max - min + 1));
    }

    /**
     * 根据正则表达式生成随机字符串
     * 
     * @param regex 正则表达式模式（不可为null）
     * @param minLength 生成字符串的最小长度（当maxLength>0时需满足minLength<=maxLength）
     * @param maxLength 生成字符串的最大长度（<=0时使用minLength或默认10）
     * @param maxAttempts 最大尝试次数（建议不小于100）
     * @return 匹配正则的随机字符串，失败返回"REGX_FAIL:"+regex
     * @throws IllegalArgumentException 当参数验证失败时抛出
     */
    public static String generateByRegex(String regex, int minLength, int maxLength, int maxAttempts) {
        // 参数校验
        if (StrUtil.isBlank(regex)) {
            throw new IllegalArgumentException("正则表达式(regex)不能为空");
        }
        if (maxLength > 0 && minLength > maxLength) {
            throw new IllegalArgumentException("最小长度(minLength)不能大于最大长度(maxLength): " + minLength + ">" + maxLength);
        }
        if (maxAttempts <= 0) {
            throw new IllegalArgumentException("最大尝试次数(maxAttempts)必须为正数: " + maxAttempts);
        }

        for (int i = 0; i < maxAttempts; i++) {
            String candidate =generate(regex);
            int candidateLength = candidate.length();
            if (candidateLength < minLength || (maxLength > 0 && candidateLength > maxLength)) {
                continue;
            }
            // 检查长度是否符合要求
            if (true) {
                return candidate;
            }
        }
        return "REGX_FAIL:" + regex; // 失败后返回错误信息
    }
  // 测试用例
    public static void main(String[] args) {
        Map<String, String> testCases = new LinkedHashMap<String, String>() {{
            put("[A-Z][a-z]{2,5}", "开头大写+小写组合");
            put("\\d{3}-\\d{4}", "电话号码格式");
            put("[aeiou]{2,4}", "元音字母组合");
            put("([01][0-9]|2[0-3]):[0-5][0-9]", "时间格式");
            put("\\p[a-z]{3}\\d{2}", "小写字母+数字组合");
            put("^[\\w-]+(\\.[\\w-]+)*\\@[\\w-]+(\\.[\\w-]+)+$", "Email");
        }};
        
        testCases.forEach((regex, desc) -> {
            System.out.println("正则: " + regex + " | 描述: " + desc);
            for (int i = 0; i < 3; i++) {
                System.out.println("  生成: " + generate(regex));
            }
        });
    }

    public static List<String> parseList(JsonNode optionsNode) {
        List<String> optionsList = new ArrayList<>();
        if (optionsNode.isArray()) {
            for (JsonNode option : optionsNode) {
                optionsList.add(option.asText());
            }
        }
        return optionsList;
    }
}